昨天寫到鍵入數字部分,今天接續把 +-/*
跟 =
的運算處理完吧~
執行 dispatch({ type: "該按鈕的數值" });
但這邊有一點要注意,如果 state.calcProgress 最末位也是 +-*/
任一個值,則新按下的 +-*/
會取代掉最末位的 +-*/
總之不可以出現 2+3+67+-
兩個運算符號相連的情況
ex: 1+1+2+
按下 -
會變成 1+1+2-
一樣在 Calculator.js 中寫
function keyOperator(currentStr, targetOpartorString) {
let returnStr = "";
let lastAlphabet = currentStr[currentStr.length - 1];
let operatorRegex = /\+|\-|\*|\//g;
if (lastAlphabet.match(operatorRegex) === null) {
// 如果最後一位不為運算符號,則將按下的運算符號添加到 currentStr 尾端
returnStr = { calcProgress: currentStr.concat(targetOpartorString) };
} else {
// 如果最後一位不為運算符號,則裁掉最後一位,並將按下的運算符號添加到 currentStr 尾端
returnStr = {
calcProgress: currentStr
.slice(0, currentStr.length - 1)
.concat(targetOpartorString)
};
}
return returnStr;
}
...
function reducer(state, action) {
let lastAlphabet = state.calcProgress[state.calcProgress.length - 1];
switch (action.type) {
// if lastAlphabet is +-*/ next +-*/ will replace it
case "+":
return keyOperator(state.calcProgress, "+");
case "-":
return keyOperator(state.calcProgress, "-");
case "*":
return keyOperator(state.calcProgress, "*");
case "/":
return keyOperator(state.calcProgress, "/");
case "=":
return handleCalculate(state.calcProgress);
case ".":
// 不能出現 .. 這種情況,其他都可以
if (lastAlphabet === ".") {
return { calcProgress: state.calcProgress };
} else {
return { calcProgress: state.calcProgress + "." };
}
...
default:
throw new Error("some error happened");
}
}
...
這裡動用一個黑魔法XD eval()
將 state.calcProgress 整個字串轉為運算的算式
但既然稱之為黑魔法,就表示不能隨便亂用,只能偶爾為之(等鐵人賽處理完再做進一步的說明吧 先賣個關子
...
function handleCalculate(currentStr) {
let result = eval(currentStr).toString();
return { calcProgress: result };
}
...
這時候計算機就大功告成了~
經驗尚淺,寫的冗長&醜的部分還請各路大大指教啊XD
CodeSandBox 的部分在這裡
https://stackoverflow.com/questions/13077923/how-can-i-convert-a-string-into-a-math-operator-in-javascript
string-concat
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/String/concat
string-slice
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice
https://regex101.com/